package com.sharp.demo.mybatis.intercept;

import com.sharp.kernel.mybatis.intercept.ExecutorIntercept;
import com.sharp.kernel.mybatis.intercept.ParameterHandlerIntercept;
import com.sharp.kernel.mybatis.intercept.ResultSetHandlerIntercept;
import com.sharp.kernel.mybatis.intercept.StatementIntercept;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Title: DemoIntercept
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2022/7/25 15:16
 */
@Slf4j
@Component
public class DemoIntercept implements ExecutorIntercept, StatementIntercept, ParameterHandlerIntercept, ResultSetHandlerIntercept {

    @Override
    public void proceed(MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) {
        log.info("ExecutorPlugin: type: {}", mappedStatement.getSqlCommandType());
        log.info("ExecutorPlugin: sql: {}", boundSql.getSql());
        log.info("ExecutorPlugin: param: {}", parameter);
    }

    @Override
    public void proceed(ParameterHandler parameterHandler) {
        MetaObject metaObject = MetaObject.forObject(parameterHandler,
                SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                new DefaultReflectorFactory());
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("mappedStatement");
        Object obj = parameterHandler.getParameterObject();
        log.info("ParameterPlugin: type: {}", mappedStatement.getSqlCommandType());
        log.info("ParameterPlugin: sql: {}", mappedStatement.getBoundSql(obj));
        log.info("ParameterPlugin: param: {}", obj);
    }

    @Override
    public void proceed(List<Object> resultList) {
        log.info("ResultSetHandlerPlugin: size: {}", resultList.size());
    }

    @Override
    public void proceed(StatementHandler statementHandler) {
        MetaObject metaObject = MetaObject.forObject(statementHandler,
                SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                new DefaultReflectorFactory());
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        Object obj = statementHandler.getParameterHandler().getParameterObject();
        BoundSql boundSql = statementHandler.getBoundSql();
        log.info("StatementPlugin: type: {}", mappedStatement.getSqlCommandType());
        log.info("StatementPlugin: sql: {}", boundSql);
        log.info("StatementPlugin: param: {}", obj);
    }
}
